package com.zusmart.core.bean.support;

import java.lang.reflect.Constructor;

import com.zusmart.base.util.ReflectionUtils;
import com.zusmart.core.bean.BeanDefinitionResolver;
import com.zusmart.core.bean.cause.BeanInstanceCreateException;
import com.zusmart.core.interceptor.InterceptorHandler;
import com.zusmart.core.proxy.ProxyManager;

public class BeanInstanceCreatorForClass extends AbstractBeanInstanceCreator {

	public BeanInstanceCreatorForClass(BeanDefinitionForClass beanDefinition) {
		super(beanDefinition);
	}

	@Override
	public BeanDefinitionForClass getBeanDefinition() {
		return (BeanDefinitionForClass) super.getBeanDefinition();
	}

	@Override
	protected Object doCreateBeanInstance() throws BeanInstanceCreateException {
		try {
			BeanDefinitionForClass beanDefinition = this.getBeanDefinition();
			BeanDefinitionResolver beanDefinitionResolver = this.getBeanDefinitionResolver();
			ProxyManager proxyManager = beanDefinition.getBeanDefinitionRegistry().getProxyManager();
			Constructor<?> constructor = beanDefinitionResolver.getBeanConstructor(beanDefinition.getBeanClass());
			if (null == constructor) {
				throw new BeanInstanceCreateException(String.format("bean constructor not found (%s)", beanDefinition));
			}
			Object[] arguments = beanDefinitionResolver.getBeanArguments(constructor);
			InterceptorHandler[] handlers = this.searchInterceptorHandlers(beanDefinition.getBeanClass());
			if (handlers.length == 0) {
				return ReflectionUtils.invokeConstructor(constructor, arguments);
			} else {
				return proxyManager.createProxyByClass(beanDefinition.getBeanClass(), constructor.getParameterTypes(), arguments, handlers);
			}
		} catch (Throwable t) {
			throw new BeanInstanceCreateException(t.getMessage(), t);
		}
	}

}